/**
 * 前面我们介绍过，在一个事件循环中，异步事件返回结果后会被放到一个任务队列中。
 * 然而，根据这个异步事件的类型，这个事件实际上会被对应的宏任务队列或者微任务队列中去。
 *
 * 并且在当前执行栈为空的时候，主线程会 查看微任务队列是否有事件存在。
 *
 * 如果不存在，那么再去宏任务队列中取出一个事件并把对应的回到加入当前执行栈；
 *
 * 如果存在，则会依次执行队列中事件对应的回调，直到微任务队列为空，然后去宏任务队列中取出最前面的一个事件，
 * 把对应的回调加入当前执行栈...如此反复，进入循环。

 我们只需记住当当前执行栈执行完毕时会立刻先处理所有微任务队列中的事件，
 然后再去宏任务队列中取出一个事件。同一次事件循环中，

 微任务永远在宏任务之前执行。


 js引擎事件：
 第一步：stack：由顶到底一次是fn4,fn3,fn2,fn1
 第二步：微队列：promise回调、mutation回调
 第三步：宏队列：dom事件回调、ajax回调、定时器




 */




/*
每一次执行宏任务之前都要取出微任务处理掉。比如下面，
当js引擎执行到宏任务队列的时候，
下面第一个setTimeout里面有微任务，当执行完这个setTimeout宏任务准备
去执行第二个setTimeout宏任务的时候，会先把第一个setTimeout里面的微任务取出来执行，
再继续执行宏任务队列剩下的任务
*/
//立即进入宏队列
setTimeout(()=>{
    console.log('宏队列timeout1 callback---10')
    Promise.resolve('宏队列里 的 微任务 timeout1 promise').then(
        value=>{ //执行到这个定时器才进入微队列
            console.log(value,'---12')
        }
    )
    console.log('宏队列timeout1 callback---11')
})

setTimeout(()=>{
    console.log('宏队列timeout2 callback---13')
})

async function asyncFn1(){
    console.log('asyncFn1---2')

    await asyncFn2()
    // 一旦遇到 await 就会先返回，等到触发的异步操作完成，
    //再执行函数体内后面的语句。可以理解为，
    //是让出了线程，跳出了 asyncFn1 函数体。
    //执行完外面的同步任务再进行剩下的

    console.log('asyncFn1 end---7')
}
async function asyncFn2(){
    console.log('asyncFn2---3')
}

// 虽然这是promise,但new操作是同步的
new Promise((resolve)=>{
    console.log('同步任务---0')
    resolve() // 立即进入微任务队列
})

//这是同步任务的
console.log('同步任务---1')

asyncFn1()

console.log('同步任务---4')


let promise1 = new Promise((resolve)=>{
    //promise在new的时候会执行到这里
    //立即进入微队列
    resolve('微队列promise resolve---8')
    //这是同步的
    console.log('promise 同步任务---5')

})
//promise的回调，微队列的回调
promise1.then((value)=>{
    console.log(value) // 第五个执行
})


Promise.resolve('微队列promise callbakc').then(
    value=>{ //立即进入微队列
        console.log(value,'---9')
    }
)

//这是同步任务的
console.log('同步任务---6')